#encoding: utf-8
from . import db, bcrypt, login_manager
from flask_login import UserMixin
from sqlalchemy import or_, and_
from datetime import datetime
from .constants import UserStatusEnum, PermissionEnum

class User(UserMixin, db.Model):
    """用户模型"""
    __tablename__ = "users"
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(20), nullable=False, unique=True, doc="用户名")
    email = db.Column(db.String(40), nullable=False, unique=True, doc="邮箱地址")
    nickname = db.Column(db.String(30), nullable=True, unique=True, doc="昵称")
    head_img = db.Column(db.String(200), nullable=True)
    password = db.Column(db.String(80), nullable=False, doc="密码")
    status = db.Column(db.Enum(UserStatusEnum), default="1", doc="用户状态")
    is_valid = db.Column(db.Boolean, default=True, doc="逻辑删除")
    created_time = db.Column(db.DateTime, doc="创建时间")
    modified_time = db.Column(db.DateTime, doc="修改时间")
    last_logined = db.Column(db.DateTime, doc="最后登录")

    blogs = db.relationship("Blog", backref="author")

    def __init__(self, username, email, password):
        self.username = username
        self.email = email
        self.password = bcrypt.generate_password_hash(password).decode("utf-8")
        self.created_time = datetime.now()

    # 通过账户获取用户
    @staticmethod
    def getUserByAccount(account):
        user = User.query.filter(or_(User.username == account, User.email == account)).filter_by(is_valid=True).first()
        return user

    @staticmethod
    def getUserById(user_id):
        user = User.query.filter_by(id=user_id, is_valid=True).first()
        return user

    # 判断密码是否正确
    def validate_password(self, password):
        return bcrypt.check_password_hash(self.password, password)

    def __repr__(self):
        return "<User {0}>".format(self.username)

@login_manager.user_loader
def load_user(user_id):
    return User.query.get(user_id)

class Role(db.Model):
    """角色模型"""
    __tablename__ = "roles"
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(20), nullable=False, doc="角色名称")
    premission = db.Column(db.Enum(PermissionEnum), nullable=False, doc="权限")
    created_time = db.Column(db.DateTime, doc="创建时间")
    modifid_time = db.Column(db.DateTime, doc="修改时间")
    is_valid = db.Column(db.Boolean, default=True, doc="逻辑删除")

    def __repr__(self):
        return "<Role {0}>".format(self.name)


class Blog(db.Model):
    """微博数据模型"""
    __tablename__ = "blogs"
    id = db.Column(db.Integer, primary_key=True)
    content = db.Column(db.String(160), nullable=False, doc="微博内容")
    is_valid = db.Column(db.Boolean, default=True, doc="逻辑删除")
    created_time = db.Column(db.DateTime, doc="创建时间")
    user_id = db.Column(db.Integer, db.ForeignKey("users.id"), doc='外键')

    def __init__(self, content, user_id):
        self.content = content
        self.user_id = user_id
        self.created_time = datetime.now()

    def __repr__(self):
        return "<Blog {0}>".format(self.id)

    @classmethod
    def getList(cls, user_id=""):
        """获取博客列表"""
        result = cls.query.filter(and_(cls.user_id==user_id if user_id else "" , cls.is_valid==True)).order_by("-created_time").all()
        return result


class Comment(db.Model):
    """评论数据模型"""
    __tablename__ = "comments"
    id = db.Column(db.Integer, primary_key=True)
    content = db.Column(db.String(160), nullable=False)

    is_valid = db.Column(db.Boolean, default=True)
    created_time = db.Column(db.DateTime)

    blog_id = db.Column(db.Integer, db.ForeignKey("blogs.id"), doc="外键，关联微博")
    user_id = db.Column(db.Integer, db.ForeignKey("users.id"), doc="外键, 关联用户")

    def __repr__(self):
        return "<Comment {0}>".format(self.id)

class Topic(db.Model):
    """话题数据模型"""
    __tablename__ = "topics"
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(30), nullable=False, unique=True)
    desc = db.Column(db.String(100), nullable=True)
    is_valid = db.Column(db.Boolean, default=True)
    created_time = db.Column(db.DateTime)

    def __init__(self, name, desc=None):
        self.name = name
        self.desc = desc
        self.created_time = datetime.now()


    def __repr__(self):
        return "<Topic {0}>".format(self.name)

    @classmethod
    def getTopicByName(cls, name):
        return cls.query.filter_by(is_valid=True, name=name).first()

class BlogRefTopic(db.Model):
    """博客关联话题"""
    __tablename__ = "blog_ref_topics"
    id = db.Column(db.Integer, primary_key=True)
    blog_id = db.Column(db.Integer, db.ForeignKey("blogs.id"), doc="外键，关联微博")
    topic_id = db.Column(db.Integer, db.ForeignKey("topics.id"), doc="外键，关联话题")
    created_time = db.Column(db.DateTime)

    def __init__(self, blog_id, topic_id):
        self.blog_id = blog_id
        self.topic_id = topic_id
        self.created_time = datetime.now()


class Friend(db.Model):
    """好友数据模型"""
    __tablename__ = "friends"
    id = db.Column(db.Integer, primary_key=True)
    from_user_id = db.Column(db.Integer, db.ForeignKey("users.id"), nullable=False)
    to_user_id = db.Column(db.Integer, db.ForeignKey("users.id"), nullable=False)
    status = db.Column(db.Enum("accepted", "refused", "default"), default="default")
    is_valid = db.Column(db.Boolean, default=True)
    created_time = db.Column(db.DateTime)

    def __init__(self, from_user_id, to_user_id):
        self.from_user_id = from_user_id
        self.to_user_id = to_user_id
        self.created_time = datetime.now()


    def __repr__(self):
        return "<Friend {0}>".format(self.id)

    @staticmethod
    def getByFromUserId(from_user_id):
        return Friend.query.filter_by(from_user_id=from_user_id, is_valid=True).first()


class BlogAtUser(db.Model):
    """@用户数据模型"""
    __tablename__ = "blog_at_users"
    id = db.Column(db.Integer, primary_key=True)
    from_user_id = db.Column(db.Integer, db.ForeignKey("users.id"), nullable=False)
    at_user_id = db.Column(db.Integer, db.ForeignKey("users.id"), nullable=False)
    blog_id = db.Column(db.Integer, db.ForeignKey("blogs.id"), nullable=False)
    created_time = db.Column(db.DateTime)

    def __init__(self, from_user_id, at_user_id, blog_id):
        self.from_user_id = from_user_id
        self.at_user_id = at_user_id
        self.blog_id = blog_id
        self.created_time = datetime.now()

    def __repr__(self):
        return "<BlogAtUser {0}>".format(self.id)
